package com.xcx.robot.mirai.key;

import com.xcx.robot.mirai.entity.team.TeamInfo;
import com.xcx.robot.mirai.entity.team.TypeNumber;
import com.xcx.robot.mirai.mp.service.ITeamInfoService;
import lombok.extern.slf4j.Slf4j;
import net.mamoe.mirai.contact.Contact;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: 邢晨旭
 * @Date: 2021/6/9 14:12
 * @Description:
 */
@Component
@Slf4j
public class TeamAlgorithm {

    public static final String typeNumberKey = "type:number:";

    @Resource
    ITeamInfoService teamInfoService;

    @Resource
    RedisTemplate<String, Object> redisTemplate;

    public void signUp(Long teamId, Contact sender, Contact receiver, String name, PositionLocation positionLocation) {
        List<TeamInfo> teamInfos = teamInfoService.getTeamInfos(teamId);
        if (teamInfos == null || teamInfos.size() < 1) {
            TeamInfo result = new TeamInfo(teamId, positionLocation, sender.getId(), name);
            teamInfoService.save(result);
            success(receiver);
            return;
        }
        TypeNumber typeNumber = typeNumber(receiver.getId());
        Integer num = 0;
        Integer currentNum = 0;
        Integer type = positionLocation.type;
        switch (type) {
            case 0:
                num = typeNumber.getWDps();
                currentNum = typeNumber.getWDpsCurrent();
                break;
            case 1:
                num = typeNumber.getNDps();
                currentNum = typeNumber.getNDpsCurrent();
                break;
            case 2:
                num = typeNumber.getHps();
                currentNum = typeNumber.getHpsCurrent();
                break;
            case 3:
                num = typeNumber.getT();
                currentNum = typeNumber.getTCurrent();
                break;
            default:
        }
        if (currentNum < num) {
            //可以报名查找位置
            getPosition(teamId, sender, receiver, name, teamInfos, positionLocation);

        }
        receiver.sendMessage("报名失败：\n当前开放位置：" + num + "\n已报名:" + currentNum);
    }


    public TypeNumber typeNumber(Long groupId) {
        Object o = redisTemplate.opsForValue().get(typeNumberKey + groupId);
        return (TypeNumber) o;
    }


    private void getPosition(Long teamId, Contact sender, Contact receiver, String name, List<TeamInfo> teamInfos, PositionLocation positionLocation) {

        switch (positionLocation.type) {
            case 0:
                List<Integer> w = teamInfos.stream().map(TeamInfo::getQIndex).filter(qIndex -> qIndex < 11).collect(Collectors.toList());
                w(teamId, sender, receiver, name, w, positionLocation);
                break;
            case 1:
                List<Integer> n = teamInfos.stream().map(TeamInfo::getQIndex).filter(qIndex -> qIndex > 10 && qIndex < 21).collect(Collectors.toList());
                n(teamId, sender, receiver, name, n, positionLocation);
                break;
            case 2:
                List<Integer> hps = teamInfos.stream().map(TeamInfo::getQIndex).filter(qIndex -> qIndex > 22 && qIndex < 26).collect(Collectors.toList());
                hps(teamId, sender, receiver, name, hps, positionLocation);
                break;
            case 3:
                List<Integer> t = teamInfos.stream().map(TeamInfo::getQIndex).filter(qIndex -> qIndex > 20 && qIndex < 26).collect(Collectors.toList());
                t(teamId, sender, receiver, name, t, positionLocation);
                break;
            default:
                error(receiver);
        }
    }

    private void w(Long teamId, Contact sender, Contact receiver, String name, List<Integer> list, PositionLocation positionLocation) {
        Set<Integer> flag = new HashSet<>(list);
        if (!list.contains(positionLocation.location)) {
            TeamInfo result = new TeamInfo(teamId, positionLocation, sender.getId(), name);
            teamInfoService.save(result);
            success(receiver);
            return;
        } else {
            for (int i = 1; i <= 10; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
            for (int i = 11; i < 16; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
        }
        error(receiver);
    }

    private void n(Long teamId, Contact sender, Contact receiver, String name, List<Integer> list, PositionLocation positionLocation) {
        Set<Integer> flag = new HashSet<>(list);
        if (!list.contains(positionLocation.location)) {
            TeamInfo result = new TeamInfo(teamId, positionLocation, sender.getId(), name);
            teamInfoService.save(result);
            success(receiver);
            success(receiver);
            return;
        } else {
            for (int i = 11; i <= 21; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
            for (int i = 6; i < 11; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
        }
        error(receiver);
    }

    private void hps(Long teamId, Contact sender, Contact receiver, String name, List<Integer> list, PositionLocation positionLocation) {
        Set<Integer> flag = new HashSet<>(list);
        if (!list.contains(positionLocation.location)) {
            TeamInfo result = new TeamInfo(teamId, positionLocation, sender.getId(), name);
            teamInfoService.save(result);
            success(receiver);
            return;
        } else {
            for (int i = 23; i <= 25; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
            for (int i = 20; i > 0; i--) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
        }
        error(receiver);
    }

    private void t(Long teamId, Contact sender, Contact receiver, String name, List<Integer> list, PositionLocation positionLocation) {
        Set<Integer> flag = new HashSet<>(list);
        if (!list.contains(positionLocation.location)) {
            TeamInfo result = new TeamInfo(teamId, positionLocation, sender.getId(), name);
            teamInfoService.save(result);
            success(receiver);
            return;
        } else {
            for (int i = 21; i <= 23; i++) {
                if (flag.add(i)) {
                    TeamInfo result = new TeamInfo(teamId, positionLocation, i, sender.getId(), name);
                    teamInfoService.save(result);
                    success(receiver);
                    return;
                }
            }
        }
        error(receiver);
    }

    private void success(Contact receiver) {
        receiver.sendMessage("报名成功");
    }

    private void error(Contact receiver) {
        receiver.sendMessage("报名失败，请联系管理");
    }
}


